package BuncoPlus;

import Framework.*;

public class BuncoPlusStrategy implements GameStrategy
{
	final int NUMBER_DICE_FACES = 6;
	final int MAX_NUMBER_OF_PLAYERS = 4;
	final int NUMBER_OF_TURNS = 6; 
	final int NUMBER_OF_DICES = 3;
	
	@Override
	public Player ComputeWinner(Game g) 
	{
		PlayerCollection p = g.getFirstPlayer();
		Player winner = p.getObject();
		
		while (p.hasNext())
		{
			if (winner.compareTo(p.next().getObject()) < 0)
				winner = p.next().getObject();
			p = (PlayerCollection) p.next();
		}
		
		return winner;
	}

	@Override
	public int ComputeScore(GenericCollection collection, int actualTurn) 
	{
		DiceCollection dices = (DiceCollection)collection;
		int result = 0;
		
		if (dicesEqual(dices))
		{
			if (dices.getObject().getResult() == actualTurn)
				return 21;
			
			return 5;
		}
		else
		{
			if (dices.getObject().getResult() == actualTurn)
				++result;
			
			while (dices.hasNext())
			{
				if ((dices = (DiceCollection)dices.next()).getObject().getResult() == actualTurn)
					++result;
			}
		}
		
		return result;
	}
	
	public boolean dicesEqual(DiceCollection d)
	{
		int equal = 0;
		
		if (!d.hasNext())
			equal = 1;
		
		while (equal == 0 && d.hasNext())
		{
			equal = d.getObject().compareTo(d.next().getObject());
			d = (DiceCollection) d.next();
		}
		
		return (equal == 0);
	}

	@Override
	public void SetupGame(Game g) 
	{
		g.setFirstPlayer(null);
		g.setPlayers(null);
		g.setDices(null);
		g.setWinner(null);
		g.setNumberMaxOfPlayers(MAX_NUMBER_OF_PLAYERS);
		g.setNumberDiceFaces(NUMBER_DICE_FACES);
		g.setNumberOfTurns(NUMBER_OF_TURNS);
		g.setNumberOfDices(NUMBER_OF_DICES);
		g.setActualTurn(1);
	}

	@Override
	public int Play(Game g) 
	{
		DiceCollection dices = g.getDices();
		DiceCollection firstDice = g.getDices();
		
		dices.getObject().roll();
		while (dices.hasNext())
			(dices = (DiceCollection)dices.next()).getObject().roll();
		
		int points = ComputeScore(firstDice, g.getActualTurn());
		g.getActualPlayer().addToScore(points);
		
		if (points == 0 || points == 21)
		{
			if (g.getPlayers().hasNext())
			{
				g.setActualPlayer(g.getPlayers().next().getObject());
				g.setPlayers((PlayerCollection) g.getPlayers().next());
			}
			else
			{
				g.setActualTurn(g.getActualTurn() + 1);
				g.setActualPlayer(g.getFirstPlayer().getObject());
				g.setPlayers((PlayerCollection) g.getFirstPlayer());
			}
		}
		
		if (g.getActualTurn() > NUMBER_OF_TURNS)
			g.setWinner(ComputeWinner(g));
		
		return points;
	}
}
